<?php

require_once 'database/FDatabase.class.php';
require_once 'database/FSQL.class.php';

class FController
{
    /**
     * Constantes que definem os tipos das colunas de tabela do banco de dados.
     */

    const TYPE_TEXT = 'text';
    const TYPE_VARCHAR = 'varchar';
    const TYPE_INT = 'int4';
    const TYPE_INTEGER = 'integer';
    const TYPE_BIGINT = 'int8';
    const TYPE_FLOAT = 'float';
    const TYPE_DOUBLE = 'double';
    const TYPE_NUMERIC = 'numeric';
    const TYPE_BOOLEAN = 'boolean';
    const TYPE_CHAR = 'char';
    const TYPE_BPCHAR = 'bpchar';
    const TYPE_DATE = 'date';
    const TYPE_TIMESTAMP = 'timestamp';
    
    protected $db;
    protected $error;
    protected $subdetails;
    protected $table;
    protected $columns;
    protected $filters;
    protected $model;
    
    private $foreignKeys;

    /**
     * Método construtor da classe.
     * Obtém os parâmetros necessários do arquivo de configuração e realiza a conexão.
     * @author Bruno Edgar Fuhr [brunofuhr@yahoo.com.br]
     * @since 29/03/2011
     * 
     * @param String $dbName - String que identifica a qual database fazer a conexão.
     */
    public function __construct($dbName = 'system')
    {
        $this->db = new FDatabase($dbName);
        //$this->filters = new stdClass();
    }

    /**
     * Método para gerar um id para um novo registro na tabela $table.
     * @author Bruno Edgar Fuhr [brunofuhr@yahoo.com.br]
     * @since 29/03/2011
     * 
     * @param $table - Tabela em que se deseja criar o novo id.
     * @param $field - Campo que é chave primária da tabela. Default 'codigo'.
     */
    public function obterIdDaTabela($table, $field = 'codigo')
    {
        if ( !$table )
        {
            $table = $this->table;
        }

        return $this->db->getIdForTable($table, $field);        
    }
    
    /**
     * Listar os nomes das colunas de uma tabela.
     * TODO: considerar esquema.
     * 
     * @param string $table Nome da tabela.
     * @return array Vetor com a listagem de colunas da tabela
     */
    public function listarColunasDaTabela($table)
    {
        if ( !$table )
        {
            $table = $this->table;
        }

        return $this->db->getTableColumns($table);
    }
    
    /**
     * Listar as informações de uma coluna da tabela.
     * 
     * @param String $table
     * @param String $column
     * @return Array
     */
    public function obterInformacaoDaColuna($column, $table = NULL)
    {
        if ( !$table )
        {
            $table = $this->table;
        }
        
        return $this->db->getColumnInfo($table, $column);
    }
    
    /**
     * Obtém as chaves primárias da tabela.
     * 
     * @param String $table - Nome da tabela
     * @return Array com os nomes e tipos das chaves primárias.
     */
    public function obterChavesPrimariasDaTabela($table = NULL)
    {
        if ( !$table )
        {
            $table = $this->table;
        }
        
        return $this->db->getTablePrimaryKey($table);
    }
    
    public function obterChavesEstrangeirasDaTabela($table = NULL)
    {
        if ( !$table )
        {
            $table = $this->table;
        }
        
        return $this->db->getTableForeignKeys($table);
    }
    
    public function obterTabelasEstrangeiras($table = NULL)
    {
        if ( !$table )
        {
            $table = $this->table;
        }
        
        return $this->db->getForeignTables($table);
    }

    /**
     * Método para executar a função query do objeto de conexão ao banco
     * @author Bruno Edgar Fuhr [brunofuhr@yahoo.com.br]
     * @since 02/12/2011
     * 
     * @param String $sql - Consulta sql.
     * @return Array - Resultado da consulta. 
     */
    public function query($sql)
    {
        if ( $this->filters['limit'] )
        {
            $this->db->setLimit($this->filters['limit']);
            
            if ( $this->filters['start'] )
            {
                $this->db->setStart($this->filters['start']);
            }
        }
        
        $result =  $this->db->query($sql);
        
        if ( !$result )
        {
            $this->error = $this->db->getError();
        }
        
        return $result;
    }
    
    /**
     * Método para executar a função execute do objeto de conexão ao banco
     * @author Bruno Edgar Fuhr [brunofuhr@yahoo.com.br]
     * @since 02/12/2011
     * 
     * @param String $sql - Comando sql.
     * @return boolean - Retorna true em caso de sucesso da operação.
     */
    public function execute($sql)
    {
        $result = $this->db->execute($sql);
        
        if ( !$result )
        {
            $this->error = $this->db->getError();
        }
        
        return $result;
    }

    /**
     * Método para retornar a mensagem de erro do SGDB.
     *
     * @return String - Mensagem de erro
     */
    public function getError()
    {
        return $this->error ? $this->error : $this->db->getError();
    }

    public function getTable() {
        return $this->table;
    }

    public function setTable($table)
    {
        $this->table = $table;
        $this->columns = $this->listarColunasDaTabela($this->table);
        
        $foreignKeys = $this->obterChavesEstrangeirasDaTabela($this->table);
        foreach( $foreignKeys as $foreignKey )
        {
            $this->addForeignKey($foreignKey);
        }
    }
    
    public function getFilters() {
        return $this->filters;
    }

    public function setFilters($filters) {
        $this->filters = $filters;
    }
    
    public function addFilter($key, $value)
    {
        $this->filters[$key] = $value;
    }
    
    public function getColumns() {
        return $this->columns;
    }

    public function setColumns($columns) {
        $this->columns = $columns;
    }

    public function getTotal()
    {
        return $this->db->getTotal();
    }
    
    public function getModel() {
        return $this->model;
    }

    public function setModel($model) {
        $this->model = $model;
    }
    
    public function getForeignKey($key)
    {
        return $this->foreignKeys[$key];
    }
    
    public function addForeignKey($foreignKey)
    {
        $this->foreignKeys[$foreignKey['attribute']] = $foreignKey;
    }

}

?>
